﻿
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Dapper;
using Common.DictComponent;
using Microsoft.IdentityModel.Tokens;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;


namespace DAL
{
    public class GoodsTypeDal
    {

        private string URL;
        private readonly AppDbContext _dbContext;
        public GoodsTypeDal(AppDbContext dbContext)
        {
            _dbContext = dbContext;

        }
        public GoodsTypeDal()
        {
            // 方式1：通过应用程序基目录获取路径（推荐）
            string baseDirectory = AppContext.BaseDirectory;
            // 处理ASP.NET Core应用中可能的路径嵌套（如bin/Debug/net6.0/）
            string configPath = Path.Combine(baseDirectory, "..", "..", "..", "appsettings.json");
            // 标准化路径（自动处理"../"等相对路径）
            configPath = Path.GetFullPath(configPath);

            // 方式2：如果方式1失败，尝试通过环境变量获取（备选）
            if (!File.Exists(configPath))
            {
                configPath = Path.Combine(Environment.CurrentDirectory, "appsettings.json");
            }

            // 检查文件是否存在
            if (!File.Exists(configPath))
            {
                throw new FileNotFoundException("配置文件不存在，请检查路径！", configPath);
            }

            // 读取连接字符串
            string jsonContent = File.ReadAllText(configPath);
            dynamic jsonObject = JsonConvert.DeserializeObject(jsonContent);
            URL = jsonObject.ConnectionStrings.SqlServer;
        }
        //bi_product_category
        public async Task<List<GoodsType>> GoodsTypesAllAsync()
        {
            using(SqlConnection conn = new SqlConnection(URL))
            {
                string sql="SELECT * FROM bi_product_category";
                return (await conn.QueryAsync<GoodsType>(sql)).ToList();
            }
        }
        public async Task<List<GoodsType>> GetAdd(
            string ParentCategoryId,
            string GoodsTypeCode,
            string GoodsTypeName,
            int SortOrder,
            int Status,
            string Remarks
            )
        {
            // 1. 校验关键参数（避免空值导致插入失败）
            if (string.IsNullOrEmpty(GoodsTypeCode))
            {
                throw new ArgumentException("货品类型编号不能为空", nameof(GoodsTypeCode));
            }
            if (string.IsNullOrEmpty(GoodsTypeName))
            {
                throw new ArgumentException("货品类型名称不能为空", nameof(GoodsTypeName));
            }
            // 2. 构建 SQL（使用修正后的语句）
            var insertSql = @"
        INSERT INTO bi_product_category (
            parent_category_id,
            goods_type_code,
            goods_type_name,
            sort_order,
            status,
            remarks,
            update_by,
            update_time,
            create_by,
            create_time,
            is_delete
        )
        VALUES (
            @ParentCategoryId,
            @GoodsTypeCode,
            @GoodsTypeName,
            @SortOrder,
            @Status,
            @Remarks,
            @UpdateBy,
            @UpdateTime,
            @CreateBy,
            @CreateTime,
            @IsDelete  
        );";
            // 查询新增记录的 SQL
            var selectSql = "SELECT * FROM bi_product_category WHERE goods_type_code = @GoodsTypeCode;";

            // 3. 准备参数（确保与 SQL 中的参数名完全一致）
            var parameters = new
            {
                ParentCategoryId = string.IsNullOrEmpty(ParentCategoryId) ? (object)DBNull.Value : ParentCategoryId,
                GoodsTypeCode,
                GoodsTypeName,
                SortOrder,
                Status,
                Remarks = string.IsNullOrEmpty(Remarks) ? "" : Remarks,
                CreateBy = GetCurrentOperator(),  // 从方法获取，确保不为 null
                CreateTime = DateTime.Now,
                UpdateBy = GetCurrentOperator(),
                UpdateTime = DateTime.Now,
                IsDelete = 0
            };

            // 4. 使用 Dapper 执行（确保 _connectionString 已正确初始化）
            using (SqlConnection con = new SqlConnection(URL))
            {
                try
                {
                    await con.OpenAsync();

                    // 执行插入
                    var rowsAffected = await con.ExecuteAsync(insertSql, parameters);
                    if (rowsAffected <= 0)
                    {
                        throw new Exception("插入数据失败，未影响任何行");
                    }

                    // 查询新增的记录
                    var result = await con.QueryAsync<GoodsType>(selectSql, new { GoodsTypeCode });
                    return result.ToList();
                }
                catch (SqlException ex)
                {
                    // 捕获数据库异常（如主键冲突、字段类型不匹配）
                    throw new Exception($"数据库错误：{ex.Message}", ex);
                }
                catch (Exception ex)
                {
                    throw new Exception($"执行新增失败：{ex.Message}", ex);
                }
            }
        }
        private string GetCurrentOperator()
        {
            // 实际项目中从登录用户上下文获取，如HttpContext.User
            return "admin"; // 临时占位
        }

        // 修改方法参数，接收开始时间和结束时间
        public async Task<List<GoodsType>> GetFuzzySearchAsync(
            string typeNameOrCode,
            int? status,
            string updateBy,
            DateTime? startTime,  // 新增：开始时间
            DateTime? endTime)    // 新增：结束时间
        {
            using (SqlConnection con = new SqlConnection(URL))
            {
                await con.OpenAsync();
                StringBuilder sqlBuilder = new StringBuilder(@"
        select 
        goods_type_id as GoodsTypeId,
        parent_category_id as ParentCategoryId,
        goods_type_code as GoodsTypeCode,
        goods_type_name as GoodsTypeName,
        sort_order as SortOrder,
        status as Status,
        is_delete as IsDelete,
        create_by as CreateBy,
        create_time as CreateTime,
        update_by as UpdateBy,
        update_time as UpdateTime,
        remarks as Remarks
        from bi_product_category
        WHERE is_delete = 0  -- 始终过滤已删除数据（关键！）
       ");  // 注意：这里已添加 WHERE 子句基础条件

                DynamicParameters parameters = new DynamicParameters();
                List<string> whereConditions = new List<string>();  // 用于存储额外条件

                // 1. 货品类型模糊匹配（编号或名称）
                if (!string.IsNullOrEmpty(typeNameOrCode))
                {
                    whereConditions.Add("(goods_type_code LIKE @TypeNameOrCode OR goods_type_name LIKE @TypeNameOrCode)");
                    parameters.Add("@TypeNameOrCode", $"%{typeNameOrCode}%");
                }

                // 2. 状态筛选
                if (status.HasValue)
                {
                    whereConditions.Add("status = @Status");
                    parameters.Add("@Status", status.Value);  // 参数名统一大写，避免冲突
                }

                // 3. 操作人模糊匹配（修改人）
                if (!string.IsNullOrEmpty(updateBy))
                {
                    whereConditions.Add("update_by LIKE @UpdateBy");
                    parameters.Add("@UpdateBy", $"%{updateBy}%");
                }

                // 4. 时间范围筛选（修改时间）
                // 4.1 只传开始时间：查询 >= 开始时间的数据
                if (startTime.HasValue && endTime.HasValue)
                {
                    whereConditions.Add("update_time >= @StartTime AND update_time < @EndTime");
                    parameters.Add("@StartTime", startTime.Value.Date);  // 取日期的0点
                    parameters.Add("@EndTime", endTime.Value.Date.AddDays(1));  // 结束日+1天（包含全天）
                }
                // 4.2 只传开始时间
                else if (startTime.HasValue)
                {
                    whereConditions.Add("update_time >= @StartTime");
                    parameters.Add("@StartTime", startTime.Value.Date);
                }
                // 4.3 只传结束时间
                else if (endTime.HasValue)
                {
                    whereConditions.Add("update_time < @EndTime");
                    parameters.Add("@EndTime", endTime.Value.Date.AddDays(1));
                }

                // 将额外条件拼接到 SQL 中
                if (whereConditions.Count > 0)
                {
                    sqlBuilder.Append(" AND " + string.Join(" AND ", whereConditions));
                }

                string sql = sqlBuilder.ToString();
                var result = (await con.QueryAsync<GoodsType>(sql, parameters)).ToList();
                return result;
            }
        }
        public async Task<List<GoodsType>> GetFuzzyUpdateAsync(
        int GoodsTypeId,
        string ParentCategoryId,
        string GoodsTypeCode,
        string GoodsTypeName,
        int SortOrder,
        int Status,
        string Remarks)
        {
            // 参数验证
            if (string.IsNullOrEmpty(GoodsTypeCode))
            {
                throw new ArgumentException("货品类型编号不能为空", nameof(GoodsTypeCode));
            }

            using (SqlConnection con = new SqlConnection(URL))
            {
                await con.OpenAsync();

                // 构建仅更新 7 个字段的 SQL，明确指定要更新的字段
                StringBuilder sqlBuilder = new StringBuilder(@"
            UPDATE bi_product_category
            SET 
                parent_category_id = @ParentCategoryId,
                goods_type_name = @GoodsTypeName,
                goods_type_code= @GoodsTypeCode,
                sort_order = @SortOrder,
                status = @Status,
                remark = @Remarks,
                updater_by = @UpdaterBy,
                update_time = GETDATE()  -- 设置更新时间为当前时间
            WHERE goods_type_id = @GoodsTypeId;

            -- 更新后查询该记录，此时 update_time 已为最新更新时间
            SELECT 
                goods_type_id, 
                parent_category_id, 
                goods_type_code, 
                goods_type_name, 
                sort_order, 
                status, 
                updater_by, 
                update_time, 
                remark AS Remarks  -- 注意这里与参数名 Remarks 对应
            FROM bi_product_category 
            WHERE goods_type_code = @GoodsTypeCode;
        ");

                // 准备参数
                var parameters = new DynamicParameters();
                parameters.Add("@GoodsTypeId", GoodsTypeId);
                parameters.Add("@ParentCategoryId", string.IsNullOrEmpty(ParentCategoryId) ? DBNull.Value : (object)ParentCategoryId);
                parameters.Add("@GoodsTypeCode", GoodsTypeCode);
                parameters.Add("@GoodsTypeName", GoodsTypeName);
                parameters.Add("@SortOrder", SortOrder);
                parameters.Add("@Status", Status);
                parameters.Add("@Remarks", string.IsNullOrEmpty(Remarks) ? DBNull.Value : (object)Remarks);
                parameters.Add("@UpdaterBy", GetCurrentOperator());  // 获取当前操作人

                // 执行更新并返回结果
                var result = (await con.QueryAsync<GoodsType>(sqlBuilder.ToString(), parameters)).ToList();
                return result;
            }
        }
        /// <summary>
        /// 逻辑删除：更新is_delete=1（Dapper实现）
        /// </summary>
        /// <param name="goodsTypeId">货品类型ID</param>
        /// <returns>受影响的行数</returns>
        public async Task<int> UpdateIsDeletedAsync(int goodsTypeId)
        {
            using (SqlConnection con = new SqlConnection(URL))
            {
                await con.OpenAsync();

                // 构建更新SQL，仅更新未删除的记录
                string sql = @"
            UPDATE bi_product_category 
            SET is_delete= 1,
                update_time = GETDATE(),   --更新操作时间为当前时间
                update_by = @UpdateBy        -- 记录操作人
            WHERE goods_type_id = @GoodsTypeId 
              AND is_delete = 0;";         // 确保只更新未删除的记录

                // 准备参数
                var parameters = new DynamicParameters();
                parameters.Add("@GoodsTypeId", goodsTypeId);
                parameters.Add("@UpdateBy", GetCurrentOperator());

                // 执行更新并返回受影响的行数
                return await con.ExecuteAsync(sql, parameters);
            }
        }
        /// <summary>
        /// 批量插入（导入专用）- 完善异常信息
        /// </summary>
        public async Task BatchInsertAsync(List<GoodsType> list, string operatorName)
        {
            if (list == null || !list.Any())
                throw new ArgumentException("批量插入的数据不能为空");

            using (var conn = new SqlConnection(URL))
            {
                await conn.OpenAsync();
                using (var tran = conn.BeginTransaction())
                {
                    try
                    {
                        string sql = @"
INSERT INTO bi_product_category (
    parent_category_id, goods_type_code, goods_type_name, sort_order, 
    status, remarks, create_by, create_time, update_by, update_time, is_delete
) VALUES (
    @ParentCategoryId, @GoodsTypeCode, @GoodsTypeName, @SortOrder, 
    @Status, @Remarks, @CreateBy, @CreateTime, @UpdateBy, @UpdateTime, 0
)";

                        foreach (var item in list)
                        {
                            // 补全系统字段并校验必填项
                            if (string.IsNullOrEmpty(item.GoodsTypeCode))
                                throw new Exception("货品类型编号不能为空（批量插入时检测）");

                            item.CreateBy = operatorName;
                            item.CreateTime = DateTime.Now;
                            item.UpdateBy = operatorName;
                            item.UpdateTime = DateTime.Now;

                            await conn.ExecuteAsync(sql, item, tran);
                        }
                        tran.Commit();
                    }
                    catch (SqlException ex)
                    {
                        tran.Rollback();
                        // 捕获数据库特定异常（如主键冲突）
                        throw new Exception($"数据库错误：{ex.Number} - {ex.Message}", ex);
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw new Exception($"批量插入失败：{ex.Message}", ex);
                    }
                }
            }
        }

        /// <summary>
        /// 检查编号是否存在（优化性能）
        /// </summary>
        public async Task<bool> ExistsCodeAsync(string goodsTypeCode)
        {
            if (string.IsNullOrEmpty(goodsTypeCode))
                return false; // 空编号视为不存在

            using (var conn = new SqlConnection(URL))
            {
                string sql = @"
SELECT 1 FROM bi_product_category 
WHERE goods_type_code = @Code AND is_delete = 0
ORDER BY goods_type_id 
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY"; // 只查1条，优化性能

                var result = await conn.QueryFirstOrDefaultAsync<int?>(sql, new { Code = goodsTypeCode });
                return result.HasValue;
            }
        }
        public async Task<List<string>> GetExistCodesAsync(List<string> codes)
        {
            using (var conn = new SqlConnection(URL))
            {
                string sql = "SELECT goods_type_code FROM bi_product_category WHERE goods_type_code IN @Codes AND is_delete = 0";
                return (await conn.QueryAsync<string>(sql, new { Codes = codes })).ToList();
            }
        }
        /// <summary>
        /// 分页查询货品类型（带筛选条件）
        /// </summary>
        public async Task<List<GoodsType>> GetPagedListAsync(
            string typeNameOrCode,
            int? status,
            string updateBy,
            DateTime? startTime,
            DateTime? endTime,
            int skip,       // 跳过的记录数（(pageNum-1)*pageSize）
            int take)       // 要获取的记录数（pageSize）
        {
            using (SqlConnection con = new SqlConnection(URL))
            {
                await con.OpenAsync();
                // 基础SQL（包含排序，确保分页稳定）
                StringBuilder sqlBuilder = new StringBuilder(@"
SELECT * FROM (
    SELECT 
        goods_type_id as GoodsTypeId,
        parent_category_id as ParentCategoryId,
        goods_type_code as GoodsTypeCode,
        goods_type_name as GoodsTypeName,
        sort_order as SortOrder,
        status as Status,
        is_delete as IsDelete,
        create_by as CreateBy,
        create_time as CreateTime,
        update_by as UpdateBy,
        update_time as UpdateTime,
        remarks as Remarks,
        -- 生成行号用于分页（按更新时间倒序，确保顺序一致）
        ROW_NUMBER() OVER (ORDER BY update_time DESC) AS RowNum
    FROM bi_product_category
    WHERE is_delete = 0  -- 过滤已删除数据
) AS T
WHERE RowNum > @Skip AND RowNum <= @Skip + @Take  -- 分页条件
");

                DynamicParameters parameters = new DynamicParameters();
                parameters.Add("@Skip", skip);
                parameters.Add("@Take", take);

                // 构建筛选条件（与GetFuzzySearchAsync逻辑一致）
                List<string> whereConditions = new List<string>();
                // 1. 货品类型编号/名称模糊匹配
                if (!string.IsNullOrEmpty(typeNameOrCode))
                {
                    whereConditions.Add("(goods_type_code LIKE @TypeNameOrCode OR goods_type_name LIKE @TypeNameOrCode)");
                    parameters.Add("@TypeNameOrCode", $"%{typeNameOrCode}%");
                }
                // 2. 状态筛选
                if (status.HasValue)
                {
                    whereConditions.Add("status = @Status");
                    parameters.Add("@Status", status.Value);
                }
                // 3. 修改人模糊匹配
                if (!string.IsNullOrEmpty(updateBy))
                {
                    whereConditions.Add("update_by LIKE @UpdateBy");
                    parameters.Add("@UpdateBy", $"%{updateBy}%");
                }
                // 4. 时间范围筛选（修改时间）
                if (startTime.HasValue && endTime.HasValue)
                {
                    whereConditions.Add("update_time >= @StartTime AND update_time < @EndTime");
                    parameters.Add("@StartTime", startTime.Value.Date);
                    parameters.Add("@EndTime", endTime.Value.Date.AddDays(1));
                }
                else if (startTime.HasValue)
                {
                    whereConditions.Add("update_time >= @StartTime");
                    parameters.Add("@StartTime", startTime.Value.Date);
                }
                else if (endTime.HasValue)
                {
                    whereConditions.Add("update_time < @EndTime");
                    parameters.Add("@EndTime", endTime.Value.Date.AddDays(1));
                }

                // 将筛选条件拼接到子查询中
                if (whereConditions.Count > 0)
                {
                    // 在子查询的WHERE后追加条件（注意：子查询已有 WHERE is_delete = 0）
                    sqlBuilder.Insert(
                        sqlBuilder.ToString().IndexOf(") AS T") - 1,  // 插入到子查询结束前
                        " AND " + string.Join(" AND ", whereConditions)
                    );
                }

                // 执行查询并返回结果
                var result = (await con.QueryAsync<GoodsType>(sqlBuilder.ToString(), parameters)).ToList();
                return result;
            }
        }
        /// <summary>
        /// 获取符合筛选条件的总记录数
        /// </summary>
        public async Task<int> GetTotalCountAsync(
            string typeNameOrCode,
            int? status,
            string updateBy,
            DateTime? startTime,
            DateTime? endTime)
        {
            using (SqlConnection con = new SqlConnection(URL))
            {
                await con.OpenAsync();
                // 基础SQL（仅查询总条数）
                StringBuilder sqlBuilder = new StringBuilder(@"
SELECT COUNT(1) 
FROM bi_product_category
WHERE is_delete = 0  -- 过滤已删除数据
");

                DynamicParameters parameters = new DynamicParameters();
                List<string> whereConditions = new List<string>();

                // 筛选条件与分页查询保持一致（复用逻辑）
                if (!string.IsNullOrEmpty(typeNameOrCode))
                {
                    whereConditions.Add("(goods_type_code LIKE @TypeNameOrCode OR goods_type_name LIKE @TypeNameOrCode)");
                    parameters.Add("@TypeNameOrCode", $"%{typeNameOrCode}%");
                }
                if (status.HasValue)
                {
                    whereConditions.Add("status = @Status");
                    parameters.Add("@Status", status.Value);
                }
                if (!string.IsNullOrEmpty(updateBy))
                {
                    whereConditions.Add("update_by LIKE @UpdateBy");
                    parameters.Add("@UpdateBy", $"%{updateBy}%");
                }
                if (startTime.HasValue && endTime.HasValue)
                {
                    whereConditions.Add("update_time >= @StartTime AND update_time < @EndTime");
                    parameters.Add("@StartTime", startTime.Value.Date);
                    parameters.Add("@EndTime", endTime.Value.Date.AddDays(1));
                }
                else if (startTime.HasValue)
                {
                    whereConditions.Add("update_time >= @StartTime");
                    parameters.Add("@StartTime", startTime.Value.Date);
                }
                else if (endTime.HasValue)
                {
                    whereConditions.Add("update_time < @EndTime");
                    parameters.Add("@EndTime", endTime.Value.Date.AddDays(1));
                }

                // 拼接筛选条件
                if (whereConditions.Count > 0)
                {
                    sqlBuilder.Append(" AND " + string.Join(" AND ", whereConditions));
                }

                // 执行查询并返回总条数
                return await con.ExecuteScalarAsync<int>(sqlBuilder.ToString(), parameters);
            }
        }
    }
}
